use std::fs;
use std::path::Path;
use std::process;
use clap::Parser;
use serde::{Deserialize, Serialize};

/// 配置文件结构
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ServerConfig {
    pub port: Option<u16>,
    pub address: Option<String>,
    pub environment: Option<String>,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct LoggingConfig {
    pub level: Option<String>,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct AppConfig {
    pub server: Option<ServerConfig>,
    pub logging: Option<LoggingConfig>,
}

/// Lightbulb Web Server - 小灯泡 Web 服务
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct Args {
    /// 服务器监听端口
    #[arg(short, long)]
    pub port: Option<u16>,

    /// 服务器监听地址
    #[arg(short, long)]
    pub address: Option<String>,

    /// 运行环境 (dev, test, prod)
    #[arg(short, long)]
    pub environment: Option<String>,

    /// 配置文件路径
    #[arg(short, long)]
    pub config: Option<String>,
}

/// 默认的日志等级
/// 日志级别 (trace, debug, info, warn, error)
const DEFAULT_LOG_LEVEL: &str = "warn";

/// 启动检查：确保 static 目录存在
pub fn bootstrap_check(address: &str, port: u16,) {
    let host = format!("{}:{}", address, port);
    let host_show = format!("http://localhost:{}", port);
    let static_path = Path::new("./static");
    if !static_path.exists() {
        eprintln!("找不到 static 文件夹: {:?}", static_path);
        eprintln!(
            "❌ 错误：找不到 `static` 文件夹。\n\
             该文件夹用于存储静态资源，请创建 `static/` 并放入 `index.html`、`404.html` 等文件。\n\
             可通过 `http:host/目录/文件名`访问资源。"
        );
        process::exit(1);
    }
    println!("static 目录检查通过: {:?}", static_path);
    println!("lightbulb web server 启动成功！");
    println!("监听地址：{}", host);
    println!("跳转首页：{}", host_show);
}

/// 读取toml配置文件
pub fn load_config(config_path: Option<String>) -> (AppConfig, Vec<String>) {
    let mut messages = Vec::new();
    if let Some(path) = config_path {
        match fs::read_to_string(&path) {
            Ok(content) => {
                match toml::from_str::<AppConfig>(&content) {
                    Ok(config) => {
                        messages.push(format!("成功加载配置文件: {}", path));
                        (config, messages)
                    }
                    Err(e) => {
                        messages.push(format!("配置文件解析失败: {}, 使用默认配置", e));
                        (AppConfig { server: None, logging: None }, messages)
                    }
                }
            }
            Err(e) => {
                messages.push(format!("无法读取配置文件 {}: {}, 使用默认配置", path, e));
                (AppConfig { server: None, logging: None }, messages)
            }
        }
    } else {
        (AppConfig { server: None, logging: None }, messages)
    }
}

/// 合并配置 (命令行参数优先级高于配置文件)
pub fn merge_config(args: &Args, file_config: &AppConfig) -> (u16, String, String) {
    let port = args.port
        .or(file_config.server.as_ref().and_then(|s| s.port))
        .unwrap_or(80);
    let address = args.address
        .clone()
        .or(file_config.server.as_ref().and_then(|s| s.address.clone()))
        .unwrap_or_else(|| "0.0.0.0".to_string());
    let environment = args.environment
        .clone()
        .or(file_config.server.as_ref().and_then(|s| s.environment.clone()))
        .unwrap_or_else(|| "test".to_string());
    
    (port, address, environment)
}

/// 初始化日志系统
pub fn init_logger(file_config: &AppConfig) {
    use std::env;
    
    // 获取日志级别配置，默认为 "warn"
    let log_level = file_config
        .logging
        .as_ref()
        .and_then(|l| l.level.as_ref())
        .map(|s| s.as_str())
        .unwrap_or(DEFAULT_LOG_LEVEL);
    
    // 设置环境变量 RUST_LOG（env_logger 需要的）
    if env::var("RUST_LOG").is_err() {
        unsafe {
            env::set_var("RUST_LOG", log_level);
        }
    }
    
    // 初始化日志
    env_logger::init();
}